/*
 * @(#)Messages.java	11/05/31
 * Copyleft 2011. All rights reversed.
 *
 * This file is part of AverageGrade.
 *
 * AverageGrade is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * AverageGrade is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with AverageGrade. If not, see <http://www.gnu.org/licenses/>.
 */

package net.grade.averagegrade.resource;

import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.MissingResourceException;
import java.util.ResourceBundle;

import net.grade.averagegrade.event.LocaleChangeListener;

/**
 * Acts as an interface to the <code>MessageBundles</code>, providing convenient methods
 * for getting strings, setting the locale and receive notifications on changes in locale.
 */
public final class Messages {

    /** Maintains a list of registered listeners that are interested in changes to locale. */
    private static final List<LocaleChangeListener> listeners = new ArrayList<LocaleChangeListener>();

    /** The <code>ResourceBundle</code> currently used for getting localized messages. */
    private static ResourceBundle messagesBundle = ResourceBundle.getBundle(
            "net.grade.averagegrade.resource.MessagesBundle");

    /**
     * Gets a string for the specified key from the backing resource bundle.
     *
     * @param key The key for the string to get.
     * @return The string for the specified key.
     * @throws NullPointerException     If <code>key</code> is <code>null</code>.
     * @throws MissingResourceException If no object for the given key can be found.
     * @throws ClassCastException       If the object found for the given key is not a string.
     */
    public static String get(final String key) {
        return messagesBundle.getString(key);
    }

    /**
     * Sets the locale for which messages are retrieved. Notifies all registered
     * locale change listeners with the locale returned from the newly created
     * bundle. The locale can be used to to determine whether the created resource
     * bundle really corresponds to the requested locale or is a fallback.
     *
     * @param locale The new locale for which messages should be retrieved.
     */
    public static void setLocale(final Locale locale) {
        messagesBundle = ResourceBundle.getBundle(
                "net.grade.averagegrade.resource.MessagesBundle", locale);
        fireLocaleChanged(messagesBundle.getLocale());
    }

    /**
     * Gets the currently set locale for which messages are retrieved.
     *
     * @return The locale for which messages are retrieved.
     */
    public static Locale getLocale() {
        return messagesBundle.getLocale();
    }

    /**
     * Registers the specified LocaleChangeListener as a listener for
     * locale change events.
     *
     * @param listener The LocaleChangeListener to register.
     */
    public static void addLocaleChangeListener(final LocaleChangeListener listener) {
        if(listener != null)
            listeners.add(listener);
    }

    /**
     * Removes the specified LocaleChangeListener as a listener for
     * locale change events.
     *
     * @param listener The LocaleChangeListener to remove.
     */
    public static void removeLocaleChangeListener(final LocaleChangeListener listener) {
        if(listener != null)
            listeners.remove(listener);
    }

    /**
     * Returns an array of all LocaleChangeListeners that are currently
     * registered as listeners for locale change events.
     *
     * @return An array of registered LocaleChangeListeners.
     */
    public static LocaleChangeListener[] getLocaleChangeListeners() {
        return listeners.toArray(new LocaleChangeListener[listeners.size()]);
    }

    /**
     * Notifies all registered listeners that the currently
     * set locale has been changed and passes along the
     * ResourceBundle for the new locale.
     *
     * @param locale The new and currently set locale.
     */
    public static void fireLocaleChanged(final Locale locale) {
        for(int i = listeners.size() - 1; i >= 0; i--)
            listeners.get(i).onLocaleChanged(locale);
    }
}